package com.lw.conexecutor.demo;

import java.util.concurrent.*;
import static java.util.concurrent.TimeUnit.MILLISECONDS;

/**异步工作机制：
 * 当执行一个FutureTask的时候，我们可以接着做别的任务，
 * 在将来的某个时间，FutureTask任务完成后会返回FutureTask对象来包装返回的结果，只要调用这个对象的get（）方法即可获取返回值。
 *
 * @author LW
 * @2021/9/18 16:15
 */
public class FutureTaskDemo {
    /**
     * FutureTask对象的三种状态
     * 未启动：创建了一个FutureTask对象但没有执行futureTask.run()；
     *
     * 已启动：futureTask.run()方法被执行的过程中；
     *
     * 已完成：futureTask.run()正常执行结束，或者futureTask被取消（futureTask.cancel()），或者执行futureTask.run()时抛出异常而异常结束；
     *
     * @param args
     * @throws InterruptedException
     */

    public static void main(String[] args) throws InterruptedException {
        /**FutureTask使用场景
         *  1、当一个线程需要等待另一个线程把某个任务执行完以后它才能继续执行时；
         *  2、有若干线程执行若干任务，每个任务最多只能被执行一次；
         *  3、当多个线程师徒执行同一个任务，但只能允许一个线程执行此任务，其它线程需要等这个任务被执行完毕以后才能继续执行时；
         */
        ThreadPoolExecutor tpe = new ThreadPoolExecutor(5, 10,100, MILLISECONDS, new ArrayBlockingQueue<Runnable>(5));
        //用FutureTask包装Runnable或者Callable对象
        FutureTask<String> future = new FutureTask<String>(new Callable<String>() {
            @Override
            public String call() {
                try{
                    String a = "return String";
                    return a;
                }
                catch(Exception e){
                    e.printStackTrace();
                    return "exception";
                }
            }
        });
        //交给线程池的Execute或submit方法执行
        tpe.submit(future);
        try{
            //FutureTask执行完后结果的获取
            System.out.println(future.get());
            //取消线程futureTask.cancel( )
            //在未启动状态调用futureTask.cancel( )会导致该任务永远不会再执行；
        }
        catch(Exception e){
            e.printStackTrace();
        }
        finally{
            //停止线程
            tpe.shutdown();
        }
    }
}
